package com.morristaedt.mirror.modules.voice;

import com.morristaedt.mirror.bean.SemanticResult;
import com.morristaedt.mirror.modules.voice.handler.DefaultHandler;
import com.morristaedt.mirror.modules.voice.handler.DishSkillHandler;
import com.morristaedt.mirror.modules.voice.handler.Handler;
import com.morristaedt.mirror.modules.voice.handler.HintHandler;
import com.morristaedt.mirror.modules.voice.handler.JokeHandler;
import com.morristaedt.mirror.modules.voice.handler.NotificationHandler;
import com.morristaedt.mirror.modules.voice.handler.OrderMenuHandler;
import com.morristaedt.mirror.modules.voice.handler.PlayerHandler;
import com.morristaedt.mirror.modules.voice.handler.RadioDisposer;
import com.morristaedt.mirror.modules.voice.handler.StoryHandler;
import com.morristaedt.mirror.modules.voice.handler.WeatherHandler;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class MessageHandler {

    private static final String KEY_SEMANTIC = "semantic";
    private static final String KEY_OPERATION = "operation";
    private static final String SLOTS = "slots";

    private SemanticResult parsedSemanticResult;
    private Handler mHandler;
    private static Map<String, Class> handlerMap = new HashMap<>();

    static {
        handlerMap.put("FOOBAR.DishSkill", DishSkillHandler.class);
        handlerMap.put("FOOBAR.MenuSkill", OrderMenuHandler.class);
        handlerMap.put("musicX", PlayerHandler.class);
        handlerMap.put("cmd", PlayerHandler.class);
        handlerMap.put("story", StoryHandler.class);
        handlerMap.put("joke", JokeHandler.class);
        handlerMap.put("radio", RadioDisposer.class);
        handlerMap.put("weather", WeatherHandler.class);
        handlerMap.put("unknown", HintHandler.class);
        handlerMap.put("notification", NotificationHandler.class);
    }

    public String getFormatMessage(String data) {
        initHandler(data);
        if (mHandler != null) {
            return mHandler.getFormatContent();
        } else {
            return "错误";
        }
    }

    public Object getDetail(String data){
        initHandler(data);
        if (mHandler instanceof WeatherHandler) {
            return ((WeatherHandler) mHandler).getDetail();
        } else if (mHandler != null) {
            return mHandler.getFormatContent();
        } else {
            return "错误";
        }
    }


    private void initHandler(String data) {
            initSemanticResult(data);
            Class handlerClass = handlerMap.get(parsedSemanticResult.service);
            if (handlerClass == null) {
                handlerClass = DefaultHandler.class;
            }
            try {
                Constructor constructor = handlerClass.getConstructor(SemanticResult.class);
                mHandler = (Handler) constructor.newInstance(parsedSemanticResult);
            } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
    }

    private void initSemanticResult(String data) {
            JSONObject semanticResult;
            parsedSemanticResult = new SemanticResult();
            try {
                semanticResult = new JSONObject(data);
                parsedSemanticResult.rc = semanticResult.optInt("rc");
                if (parsedSemanticResult.rc == 4) {
                    parsedSemanticResult.service = "unknown";
                } else if (parsedSemanticResult.rc == 1) {
                    parsedSemanticResult.service = semanticResult.optString("service");
                    parsedSemanticResult.answer = "语义错误";
                } else {
                    parsedSemanticResult.service = semanticResult.optString("service");
                    parsedSemanticResult.answer = semanticResult.optJSONObject("answer") == null ?
                            "已为您完成操作" : semanticResult.optJSONObject("answer").optString("text");
                    boolean isAIUI3_0 = semanticResult.has(KEY_OPERATION);
                    if (isAIUI3_0) {
                        JSONObject semantic = semanticResult.optJSONObject(KEY_SEMANTIC);
                        if (semantic != null) {
                            JSONObject slots = semantic.optJSONObject(SLOTS);
                            JSONArray fakeSlots = new JSONArray();
                            Iterator<String> keys = slots.keys();
                            while (keys.hasNext()) {
                                JSONObject item = new JSONObject();
                                String name = keys.next();
                                item.put("name", name);
                                item.put("value", slots.get(name));

                                fakeSlots.put(item);
                            }

                            semantic.put(SLOTS, fakeSlots);
                            semantic.put("intent", semanticResult.optString(KEY_OPERATION));
                            parsedSemanticResult.semantic = semantic;
                        }
                    } else {
                        parsedSemanticResult.semantic = semanticResult.optJSONArray(KEY_SEMANTIC) == null ?
                                semanticResult.optJSONObject(KEY_SEMANTIC) :
                                semanticResult.optJSONArray(KEY_SEMANTIC).optJSONObject(0);
                    }
                    parsedSemanticResult.answer = parsedSemanticResult.answer.replaceAll("\\[[a-zA-Z0-9]{2}\\]", "");
                    parsedSemanticResult.data = semanticResult.optJSONObject("data");
                }
            } catch (JSONException e) {
                parsedSemanticResult.rc = 4;
                parsedSemanticResult.service = "unknown";
            }

        }

}
